#ifndef FRICTIONSURFACE_H
#define FRICTIONSURFACE_H

#pragma once

#include "../../ToolkitLayer.h"
#include <LDF/VisComponentStrategy.h>
#include <IBuffer/IBuffer.h>


/**
 * This strategy provides a surface with a buffer containing values of
 * (dynamic) friction coefficients for the associated component. It is used by
 * TossingStrategy and TossingRNTStrategy to calculate the movement of a tossed
 * component (instead of the default dynamic friction coefficient). The
 * friction values must be between 0.0 and 1.0.
 *
 * @author Fabricio Anastacio - fabriciocfa@yahoo.com
 * @since August 14, 2007
 */
class TOOLKITLAYER_API FrictionSurfaceStrategy : public VisComponentStrategy
{
	// Attributes
protected:
	/** Width of the border of the buffer (with stop values). */
	unsigned int borderWidth;
	/** Height of the border of the buffer (with stop values). */
	unsigned int borderHeight;
	/** Friction coefficient applied to the inner region of the surface. */
	float innerFriction;
	/** Friction coefficient applied to the border region of the surface (stop value). */
	float borderFriction;

	/** Friction buffer type identifier. */
	unsigned int frictionBufferType;


	// Methods
public:
	/**
	 * Constructs a friction surface strategy.
	 */
	FrictionSurfaceStrategy(void);
	/**
	 * Destroys this strategy.
	 */
	~FrictionSurfaceStrategy(void);


	// ACCESSOR METHODS
	/**
	 * Returns the width of the border of the surface (region where the objects
	 * should halt).
	 *
	 * @return the width of the border.
	 */
	inline unsigned int getBorderWidth() { return borderWidth; };
	/**
	 * Sets the width of the border of the surface (region where the objects
	 * should halt).
	 *
	 * @param w the value to be set as the border width.
	 */
	inline void setBorderWidth(unsigned int w) { borderWidth = w; };
	/**
	 * Returns the height of the border of the surface (region where the
	 * objects should halt).
	 *
	 * @return the height of the border.
	 */
	inline unsigned int getBorderHeight() { return borderHeight; };
	/**
	 * Sets the height of the border of the surface (region where the objects
	 * should halt).
	 *
	 * @param h the value to be set as the border height.
	 */
	inline void setBorderHeight(unsigned int h) { borderHeight = h; };
	/**
	 * Returns the friction coefficient for the inner part of the surface.
	 *
	 * @return the friction coefficient for the inner part of the surface.
	 */
	inline float getInnerFriction() { return innerFriction; };
	/**
	 * Sets the friction coefficient for the inner part of the surface.
	 *
	 * @param coeff the value to be set as friction coefficient for the inner
	 * part of the surface.
	 */
	inline void setInnerFriction(float coeff) { innerFriction = coeff; };
	/**
	 * Returns the friction coefficient for the border of the surface.
	 *
	 * @return the friction coefficient for the border of the surface.
	 */
	inline float getBorderFriction() { return borderFriction; };
	/**
	 * Sets the friction coefficient for the border of the surface.
	 *
	 * @param coeff the value to be set as friction coefficient for the border
	 * of the surface.
	 */
	inline void setBorderFriction(float coeff) { borderFriction = coeff; };

protected:
	/**
	 * Initializes the properties (i. e., i-buffers) of the associated
	 * component.
	 */
	void initProperties();
	/**
	 * Defines the strategy to be used when the associated component is
	 * resized.
	 *
	 * @param width the new width of the component.
	 * @param height the new height of the component.
	 */
	void resize(unsigned int width, unsigned int height);
	

protected:
	/**
	 * Fills the friction buffer with the default values.
	 *
	 * @param buffer the button buffer to be filled.
	 */
	void fillFrictionBuffer(IBuffer<float>* buffer);
};

#endif // FRICTIONSURFACE_H
